﻿//FinamUrl.cs
//Copyright (c) 2013 StockSharp LLC, all rights reserved.
//This code module is part of StockSharp library.
//This code is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.
//See the file License.txt for the license details.
//More info on: http://stocksharp.com

namespace StockSharp.Algo.History.Finam
{
	using System;
	using System.Collections.Generic;
	using System.Linq;

	using Ecng.Collections;
	using Ecng.Common;

	using StockSharp.BusinessEntities;

	class FinamUrl
	{
		private enum Parts
		{
			From,
			To,
			TimeFrame,
			Security,
		}

		private static readonly SynchronizedDictionary<TimeSpan, int> _timeFrameIds = new SynchronizedDictionary<TimeSpan, int>
		{
			{ TimeSpan.Zero, 1 },
			{ TimeSpan.FromMinutes(1), 2 },
			{ TimeSpan.FromMinutes(5), 3 },
			{ TimeSpan.FromMinutes(10), 4 },
			{ TimeSpan.FromMinutes(15), 5 },
			{ TimeSpan.FromMinutes(30), 6 },
			{ TimeSpan.FromMinutes(60), 7 },
			{ TimeSpan.FromDays(1), 8 }
		};

		private readonly Dictionary<Parts, Func<string>> _parts = new Dictionary<Parts, Func<string>>();

		public Uri Uri
		{
			get { return ("http://195.128.78.52/TempData.txt?d=d&f=TempData&e=.txt&dtf=1&tmf=1&MSOR=0&cn=SECURITYCODE&sep=3&sep2=1&"
			              + _parts.Select(p => p.Value()).Join("&")).To<Uri>(); }
		}

		public FinamUrl From(DateTime date)
		{
			_parts[Parts.From] = () => "df={0}&mf={1}&yf={2}".Put(date.Day.ToString("#0"), (date.Month - 1).ToString("#0"), date.Year.ToString("0000"));
			return this;
		}

		public FinamUrl To(DateTime date)
		{
			_parts[Parts.To] = () => "dt={0}&mt={1}&yt={2}".Put(date.Day.ToString("#0"), (date.Month - 1).ToString("#0"), date.Year.ToString("0000"));
			return this;
		}

		public FinamUrl TimeFrame(TimeSpan tf)
		{
			int p;

			if (!_timeFrameIds.TryGetValue(tf, out p))
				throw new ArgumentOutOfRangeException("tf", tf, "TimeFrame должен быть 0, 1, 5, 10, 15, 30, 60 мин или 1 день.");

			_parts[Parts.TimeFrame] = () => "p={0}&datf={1}".Put(p, (tf == TimeSpan.Zero) ? 11 : 5);
			return this;
		}

		public FinamUrl Security(Security security)
		{
			if (security == null)
				throw new ArgumentNullException("security");

			var marketId = (long)security.ExtensionInfo[FinamHistorySource.FinamMarketIdField];
			var securityId = (long)security.ExtensionInfo[FinamHistorySource.FinamSecurityIdField];

			return Security(marketId, securityId);
		}

		public FinamUrl Security(FinamSecurityInfo securityInfo)
		{
			if (securityInfo == null)
				throw new ArgumentNullException("securityInfo");

			return Security(securityInfo.FinamMarketId, securityInfo.FinamSecurityId);
		}

		private FinamUrl Security(long marketId, long securityId)
		{
			_parts[Parts.Security] = () => "m={0}&em={1}".Put(marketId, securityId);
			return this;
		}
	}
}